package disjunction.examples.entities
{	
	import disjunction.core.EntityListView;
	import disjunction.core.EntityView;
	import disjunction.core.IView;
	import disjunction.extensions.view.DisplayObjectEntity2D;
	import disjunction.extensions.view.DisplayObjectEntityListView;
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Shape;
	
	/**
	 * @author Nick Wiggill
	 */
	
	public class DemoView extends EntityListView
	{
		/** A subset of entities after culling, to be rendered. */
		//private var _entitiesToRender:Array = [];
		
		//private var _camera:ICamera;
		//renderer set by specific class in its implementation 
		//public var entityRenderer:EntityRenderer;
		//TODO should be wrapped in an interface to add and remove, as this breaks encapsulation.
		//public var renderers:Array = [];
		
		public var debug:Boolean = true;
		
		public override function update(timeDeltaMs:uint):void
		{
			trace('custom view update');
			//_entitiesToRender = _entities.concat();
			//_camera.update(_entitiesToRender); //modifies list directly
		
			//Update & Render standard entity views
			for each (var entityView:* in _entities)
			{
				trace('entity ',entityView.model.position.x, ', ', entityView.model.position.y);
				entityView.displayObject.x = entityView.model.position.x;
				entityView.displayObject.y = entityView.model.position.y;
			}
			
			//Render debug entities if appropriate
			if (debug)
			{
				
			}
		}
		
		public override function addEntityView(entity:*):void
		{
			
			//will throw cast error if element in entity view list is incorrect type
			var entityView:* = _viewsByModel[entity];
			
			if (entityView == null)
			{
				
				//creator is non optional, so we will fail with a NPE if the creator is null
				entityView = createEntityView(entity); //createFor()?
				entityView.model = entity;
				//add to own lists (entities)
				_entities.push(entityView);
				_viewsByModel[entity] = entityView;
				
				//add to rendering system list (displayobjects)
				(context as DisplayObjectContainer).addChild((entityView as DisplayObjectEntity2D).displayObject);
			}
		}
		
		/** Removes an entity from the view. */
		public override function removeEntityView(entity:*):void
		{
			var entityView:EntityView = _viewsByModel[entity];
			
			if (entityView != null)
			{
				entityView.model = null;
				//remove from rendering system list (displayobjects)
				(context as DisplayObjectContainer).removeChild((entityView as DisplayObjectEntity2D).displayObject);	
				
				//remove from own lists (entities)
				_entities.splice(_entities.lastIndexOf(entityView), 1);
				delete _viewsByModel[entity];
				
				//destroy the object
				//if (entityDestroyer) //since this optional, check if it applies
				//{		
				destroyEntityView(entity); //model? view? should be destroyFor()?
				//}
			}
		}
		
		protected override function createEntityView(entityModel:*):*
		{
			var colour:uint;
			//var entityModel:DemoEntityModel = entityModel;// as DemoEntityModel;
			switch(entityModel.type)
			{
				case DemoEntityModel.TYPE_BOUNCER: colour = 0xFFFF00; break;
				case DemoEntityModel.TYPE_DANCER: colour = 0x00FF00; break;
				case DemoEntityModel.TYPE_WANDERER: colour = 0x00FFFF; break;
				case DemoEntityModel.TYPE_JITTERER: colour = 0xFF0000; break;
			}
			
			var shape:Shape = new Shape();
			drawSmileyOn(shape, entityModel.radius, colour);
			var entityView:DisplayObjectEntity2D = new DisplayObjectEntity2D()
			entityView.displayObject = shape;
			//entityView.model = entityModel;
			return entityView;
		}
		
		
		private function drawSmileyOn(shape:Shape, radius:Number, colour:uint):void
		{			
			//face
			shape.graphics.beginFill(colour);
			shape.graphics.drawCircle(0, 0, radius);
			shape.graphics.endFill();
			
			//left eye
			shape.graphics.beginFill(0x000000);
			shape.graphics.drawCircle(-2.5, -2.5, 1);
			shape.graphics.endFill();
			
			//right eye
			shape.graphics.beginFill(0x000000);
			shape.graphics.drawCircle(2.5, -2.5, 1);
			shape.graphics.endFill();
			
			//mouth
			shape.graphics.beginFill(0x000000);
			shape.graphics.lineStyle(1);
			shape.graphics.moveTo(0, 3);
			shape.graphics.lineTo(-3, 2);
			shape.graphics.lineTo(3, 2);
			shape.graphics.endFill();
		}
	}
}